#include "../include/ftp.h"

static char* file_type(mode_t md)
{
    if(S_ISREG(md))
    {
        return "-";	
    }else if(S_ISDIR(md))
    {
        return "d";
    }else if(S_ISFIFO(md))
    {
        return "p";
    }else 
    {
        return "o" ;
    }
}
static void do_ls(psession_t ps) 
{
    DIR* pdir = opendir("./");
    if(pdir == NULL)
    {
        int flag = -1 ;
        send(ps ->sess_sfd, &flag, sizeof(int), 0);
    }else
    {
        struct dirent* mydir ;
        int len ;
        while( (mydir = readdir(pdir)) != NULL)
        {
            if(strncmp(mydir->d_name, ".", 1) == 0 || strncmp(mydir->d_name,"..", 2) == 0)
            {
                continue ;
            }
            struct stat mystat;
            bzero(&mystat, sizeof(mystat));
            stat(mydir->d_name, &mystat);
            bzero(ps ->sess_buf, 1024);
            sprintf(ps ->sess_buf, "%-2s%-20s %10ldB", file_type(mystat.st_mode),mydir->d_name, mystat.st_size );
            len =  strlen(ps ->sess_buf);
            send(ps ->sess_sfd, &len, sizeof(int), 0);
            sendn(ps ->sess_sfd, ps ->sess_buf, len);
        }
        len = 0 ;
        send(ps ->sess_sfd, &len, sizeof(int), 0);
    }

}
static void do_cd(psession_t ps) 
{
    char dir[128]= "";
    sscanf(ps ->sess_buf +3, "%s", dir);
    chdir(dir);
    getcwd(dir, 128);
    int len = strlen(dir);
    send(ps ->sess_sfd, &len, sizeof(int), 0);
    sendn(ps ->sess_sfd, dir, strlen(dir));
}
static void do_pwd(psession_t ps) 
{
    bzero(ps ->sess_buf, BUF_SIZE);
    getcwd(ps ->sess_buf, BUF_SIZE);
    int len = strlen(ps ->sess_buf);
    send(ps ->sess_sfd, &len, sizeof(int), 0);
    sendn(ps ->sess_sfd, ps ->sess_buf, len);

}
static void do_gets(psession_t ps) 
{
    char file_name[256];
    int file_pos = 5 ;
    while(bzero(file_name, 256),sscanf(ps ->sess_buf + file_pos,"%s", file_name ) == 1)
    {
        file_pos += strlen(file_name) + 1; 
#if 1
        if(sendFile(ps ->sess_sfd, file_name) == 0){
#else 
        if(upload(ps ->sess_sfd, file_name) == 0){
#endif
            printf(" file-> %s upload success\n", file_name);
        }else 
        {
            printf(" file-> %s upload failed\n", file_name);
        }

    }

}
static void do_mkdir(psession_t ps)
{
    char dir_name[256] = {0};
    sscanf(ps ->sess_buf + 6,"%s", dir_name );
    if(mkdir(dir_name, 0664) == 0){
        printf("dir %s create success\n",dir_name);
        sprintf(ps ->sess_buf, "%s create success", ps ->sess_buf + 6);
    }
    else {
        printf("dir %s create failed\n",dir_name);
        sprintf(ps ->sess_buf, "%s create failed", ps ->sess_buf + 6);
    }
    int len = strlen(ps ->sess_buf);
    send(ps ->sess_sfd, &len, sizeof(int), 0);
    sendn(ps ->sess_sfd, ps ->sess_buf, len);
}
static void do_puts(psession_t ps) //puts a.txt b.txt
{
    char file_name[256];
    int file_pos = 5 ;
    while(bzero(file_name, 256), sscanf(ps ->sess_buf + file_pos,"%s", file_name) == 1)
    {
        file_pos += strlen(file_name) + 1 ;
#if 1
        if(recvFile(ps -> sess_sfd, file_name) == 0)
#else 
        if(download(ps -> sess_sfd, file_name) == 0)
#endif
        {
            printf("file -> %s download success \n", file_name);
        }else
        {

            printf("file -> %s download failed \n", file_name);
        }
    }
}
static void do_remove(psession_t ps)// remove file 
{
    char cmd[256] ={0};
    struct stat mystat;
    bzero(&mystat, sizeof(mystat));
    stat(ps->sess_buf+3, &mystat);
    if(strncmp (file_type(mystat.st_mode),"d",1)==0)

    {
        sprintf(cmd, "rm -f -r %s", ps ->sess_buf + 3);
    }
    else
        sprintf(cmd, "rm -f %s", ps ->sess_buf + 3);
    system(cmd);
    sprintf(ps ->sess_buf, "%s removed", ps ->sess_buf + 3);
    int len = strlen(ps ->sess_buf);
    send(ps ->sess_sfd, &len, sizeof(int),0);
    sendn(ps ->sess_sfd, ps ->sess_buf, len);
    bzero(ps ->sess_buf, BUF_SIZE);
}
void client_handle(psession_t ps)
{

    socket_t fd_client = ps -> sess_sfd ;
    int cmd_len = 0 ;
    int recv_ret ;
    while(1)
    {
        bzero(ps -> sess_buf, BUF_SIZE);
        recv_ret = recv(fd_client, &cmd_len, sizeof(int),0);
        if(cmd_len == 0 || recv_ret == 0)
        {
            printf("client exit !\n");
            close(ps ->sess_sfd);
            free(ps);
            exit(1);
        }
        recvn(fd_client, ps->sess_buf, cmd_len);
        if(strncmp("cd", ps ->sess_buf, 2) == 0)
        {
            do_cd(ps);
        }else if(strncmp("ls", ps ->sess_buf, 2) == 0)
        {
            do_ls(ps);
        }else if( strncmp("puts", ps ->sess_buf, 4)== 0)
        {
            do_puts(ps);
        }else if( strncmp("gets", ps ->sess_buf, 4)== 0)
        {
            do_gets(ps);

        }else if( strncmp("rm", ps ->sess_buf, 2)== 0)
        {
            do_remove(ps);

        }else if(strncmp("pwd", ps ->sess_buf, 3) == 0) 
        {
            do_pwd(ps);

        }else if(strncmp("mkdir", ps ->sess_buf, 5) == 0)
        {
            do_mkdir(ps);
        }else 
        {
            continue ;
        }


    }
}
